package zpp_nape.geom;
import zpp_nape.Config;
import zpp_nape.Const;
import zpp_nape.util.Flags;
import DummyNapeMain;
import zpp_nape.util.Math;
import zpp_nape.util.Names;
import zpp_nape.util.Pool;
import zpp_nape.util.Lists;
import zpp_nape.shape.Circle;
import zpp_nape.shape.Edge;
import zpp_nape.space.Space;
import zpp_nape.shape.Polygon;
import zpp_nape.shape.Shape;
import zpp_nape.phys.FeatureMix;
import zpp_nape.phys.FluidProperties;
import zpp_nape.phys.Material;
import zpp_nape.phys.Body;
import zpp_nape.geom.Distance;
import zpp_nape.geom.Mat23;
import zpp_nape.geom.Vec2;
import zpp_nape.geom.VecMath;
import zpp_nape.geom.Collide;
import zpp_nape.dynamics.Arbiter;
import zpp_nape.dynamics.Contact;
import zpp_nape.dynamics.InteractionFilter;
import zpp_nape.constraint.Constraint;
import zpp_nape.dynamics.SpaceArbiterList;
import zpp_nape.constraint.Matrices;
import zpp_nape.constraint.PivotJoint;
import zpp_nape.constraint.WeldJoint;
import nape.util.Flags;
import nape.util.Lists;
import nape.util.Debug;
import nape.space.Space;
import nape.shape.Circle;
import nape.shape.Polygon;
import nape.shape.Edge;
import nape.shape.Shape;
import nape.phys.FluidProperties;
import nape.phys.Material;
import nape.phys.Body;
import nape.geom.AABB;
import nape.geom.Geom;
import nape.geom.Mat23;
import nape.geom.Vec2;
import nape.dynamics.Contact;
import nape.dynamics.Arbiter;
import nape.dynamics.InteractionFilter;
#if swc@:keep#end class ZPP_AABB{
    public var _invalidate:ZPP_AABB->Dynamic;
    public var _validate:Void->Dynamic;
    public var immutable:Bool;
    #if(flash9&&flib)@:ns("flibdel")#end public inline function validate(){
        if(_validate!=null)_validate();
    }
    #if(flash9&&flib)@:ns("flibdel")#end public inline function invalidate(){
        if(wrap_min!=null)wrap_min.zpp_inner.invalidate();
        if(wrap_max!=null)wrap_max.zpp_inner.invalidate();
        if(_invalidate!=null)_invalidate(this);
    }
    public var outer:AABB;
    #if(flash9&&flib)@:ns("flibdel")#end public inline function wrapper(){
        if(outer==null){
            outer=new AABB();
            {
                var o=outer.zpp_inner;
                {
                    #if NAPE_ASSERT var res={
                        o!=null;
                    };
                    if(!res)throw "assert("+"o!=null"+") :: "+("Free(in T: "+"ZPP_AABB"+", in obj: "+"outer.zpp_inner"+")");
                    #end
                };
                o.free();
                o.next=ZPP_AABB.zpp_pool;
                ZPP_AABB.zpp_pool=o;
            };
            outer.zpp_inner=this;
        }
        return outer;
    }
    static public var zpp_pool:ZPP_AABB;
    public var next:ZPP_AABB;
    #if(flash9&&flib)@:ns("flibdel")#end public inline function free(){
        outer=null;
        wrap_min=wrap_max=null;
    }
    public function new(){}
    public static inline function get(minx:Float,miny:Float,maxx:Float,maxy:Float){
        var ret={
            if(ZPP_AABB.zpp_pool==null)new ZPP_AABB();
            else{
                var ret=ZPP_AABB.zpp_pool;
                ZPP_AABB.zpp_pool=ret.next;
                ret;
            }
        };
        {
            ret.minx=minx;
            ret.miny=miny;
            {
                #if NAPE_ASSERT var res={
                    !({
                        #if flash9 var ret:Bool=untyped __global__["isNaN"](ret.minx);
                        ret;
                        #else Math.isNaN(ret.minx);
                        #end
                    });
                };
                if(!res)throw "assert("+"!assert_isNaN(ret.minx)"+") :: "+("vec_set(in n: "+"ret.min"+",in x: "+"minx"+",in y: "+"miny"+")");
                #end
            };
            {
                #if NAPE_ASSERT var res={
                    !({
                        #if flash9 var ret:Bool=untyped __global__["isNaN"](ret.miny);
                        ret;
                        #else Math.isNaN(ret.miny);
                        #end
                    });
                };
                if(!res)throw "assert("+"!assert_isNaN(ret.miny)"+") :: "+("vec_set(in n: "+"ret.min"+",in x: "+"minx"+",in y: "+"miny"+")");
                #end
            };
        };
        {
            ret.maxx=maxx;
            ret.maxy=maxy;
            {
                #if NAPE_ASSERT var res={
                    !({
                        #if flash9 var ret:Bool=untyped __global__["isNaN"](ret.maxx);
                        ret;
                        #else Math.isNaN(ret.maxx);
                        #end
                    });
                };
                if(!res)throw "assert("+"!assert_isNaN(ret.maxx)"+") :: "+("vec_set(in n: "+"ret.max"+",in x: "+"maxx"+",in y: "+"maxy"+")");
                #end
            };
            {
                #if NAPE_ASSERT var res={
                    !({
                        #if flash9 var ret:Bool=untyped __global__["isNaN"](ret.maxy);
                        ret;
                        #else Math.isNaN(ret.maxy);
                        #end
                    });
                };
                if(!res)throw "assert("+"!assert_isNaN(ret.maxy)"+") :: "+("vec_set(in n: "+"ret.max"+",in x: "+"maxx"+",in y: "+"maxy"+")");
                #end
            };
        };
        return ret;
    }
    #if(flash9&&flib)@:ns("flibdel")#end public inline function copy()return ZPP_AABB.get(minx,miny,maxx,maxy)#if(flash9&&flib)@:ns("flibdel")#end public inline function width()return maxx-minx#if(flash9&&flib)@:ns("flibdel")#end public inline function height()return maxy-miny public var minx:Float;
    public var miny:Float;
    public var wrap_min:Vec2;
    #if(flash9&&flib)@:ns("flibdel")#end public inline function get_min(){
        if(wrap_min==null){
            wrap_min=new Vec2(minx,miny);
            wrap_min.zpp_inner.inuse=true;
            if(immutable)wrap_min.zpp_inner.immutable=true;
            else wrap_min.zpp_inner._invalidate=mod_min;
            wrap_min.zpp_inner._validate=dom_min;
        }
        return wrap_min;
    }
    public function dom_min(){
        validate();
        {
            wrap_min.x=minx;
            wrap_min.y=miny;
            {
                #if NAPE_ASSERT var res={
                    !({
                        #if flash9 var ret:Bool=untyped __global__["isNaN"](wrap_min.x);
                        ret;
                        #else Math.isNaN(wrap_min.x);
                        #end
                    });
                };
                if(!res)throw "assert("+"!assert_isNaN(wrap_min.x)"+") :: "+("vec_set(in n: "+"wrap_min."+",in x: "+"minx"+",in y: "+"miny"+")");
                #end
            };
            {
                #if NAPE_ASSERT var res={
                    !({
                        #if flash9 var ret:Bool=untyped __global__["isNaN"](wrap_min.y);
                        ret;
                        #else Math.isNaN(wrap_min.y);
                        #end
                    });
                };
                if(!res)throw "assert("+"!assert_isNaN(wrap_min.y)"+") :: "+("vec_set(in n: "+"wrap_min."+",in x: "+"minx"+",in y: "+"miny"+")");
                #end
            };
        };
    }
    public function mod_min(min:ZPP_Vec2){
        if(min.x!=minx||min.y!=miny){
            {
                minx=min.x;
                miny=min.y;
                {
                    #if NAPE_ASSERT var res={
                        !({
                            #if flash9 var ret:Bool=untyped __global__["isNaN"](minx);
                            ret;
                            #else Math.isNaN(minx);
                            #end
                        });
                    };
                    if(!res)throw "assert("+"!assert_isNaN(minx)"+") :: "+("vec_set(in n: "+"min"+",in x: "+"min.x"+",in y: "+"min.y"+")");
                    #end
                };
                {
                    #if NAPE_ASSERT var res={
                        !({
                            #if flash9 var ret:Bool=untyped __global__["isNaN"](miny);
                            ret;
                            #else Math.isNaN(miny);
                            #end
                        });
                    };
                    if(!res)throw "assert("+"!assert_isNaN(miny)"+") :: "+("vec_set(in n: "+"min"+",in x: "+"min.x"+",in y: "+"min.y"+")");
                    #end
                };
            };
            invalidate();
        }
    }
    public var maxx:Float;
    public var maxy:Float;
    public var wrap_max:Vec2;
    #if(flash9&&flib)@:ns("flibdel")#end public inline function get_max(){
        if(wrap_max==null){
            wrap_max=new Vec2(maxx,maxy);
            wrap_max.zpp_inner.inuse=true;
            if(immutable)wrap_max.zpp_inner.immutable=true;
            else wrap_max.zpp_inner._invalidate=mod_max;
            wrap_max.zpp_inner._validate=dom_max;
        }
        return wrap_max;
    }
    public function dom_max(){
        validate();
        {
            wrap_max.x=maxx;
            wrap_max.y=maxy;
            {
                #if NAPE_ASSERT var res={
                    !({
                        #if flash9 var ret:Bool=untyped __global__["isNaN"](wrap_max.x);
                        ret;
                        #else Math.isNaN(wrap_max.x);
                        #end
                    });
                };
                if(!res)throw "assert("+"!assert_isNaN(wrap_max.x)"+") :: "+("vec_set(in n: "+"wrap_max."+",in x: "+"maxx"+",in y: "+"maxy"+")");
                #end
            };
            {
                #if NAPE_ASSERT var res={
                    !({
                        #if flash9 var ret:Bool=untyped __global__["isNaN"](wrap_max.y);
                        ret;
                        #else Math.isNaN(wrap_max.y);
                        #end
                    });
                };
                if(!res)throw "assert("+"!assert_isNaN(wrap_max.y)"+") :: "+("vec_set(in n: "+"wrap_max."+",in x: "+"maxx"+",in y: "+"maxy"+")");
                #end
            };
        };
    }
    public function mod_max(max:ZPP_Vec2){
        if(max.x!=maxx||max.y!=maxy){
            {
                maxx=max.x;
                maxy=max.y;
                {
                    #if NAPE_ASSERT var res={
                        !({
                            #if flash9 var ret:Bool=untyped __global__["isNaN"](maxx);
                            ret;
                            #else Math.isNaN(maxx);
                            #end
                        });
                    };
                    if(!res)throw "assert("+"!assert_isNaN(maxx)"+") :: "+("vec_set(in n: "+"max"+",in x: "+"max.x"+",in y: "+"max.y"+")");
                    #end
                };
                {
                    #if NAPE_ASSERT var res={
                        !({
                            #if flash9 var ret:Bool=untyped __global__["isNaN"](maxy);
                            ret;
                            #else Math.isNaN(maxy);
                            #end
                        });
                    };
                    if(!res)throw "assert("+"!assert_isNaN(maxy)"+") :: "+("vec_set(in n: "+"max"+",in x: "+"max.x"+",in y: "+"max.y"+")");
                    #end
                };
            };
            invalidate();
        }
    }
    #if(flash9&&flib)@:ns("flibdel")#end public inline function intersectX(x:ZPP_AABB){
        return!(x.minx>maxx||minx>x.maxx);
    }
    #if(flash9&&flib)@:ns("flibdel")#end public inline function intersectY(x:ZPP_AABB){
        return!(x.miny>maxy||miny>x.maxy);
    }
    #if(flash9&&flib)@:ns("flibdel")#end public inline function intersect(x:ZPP_AABB){
        return!(x.miny>maxy||miny>x.maxy||x.minx>maxx||minx>x.maxx);
    }
    #if(flash9&&flib)@:ns("flibdel")#end public inline function combine(x:ZPP_AABB){
        if(x.minx<minx)minx=x.minx;
        if(x.maxx>maxx)maxx=x.maxx;
        if(x.miny<miny)miny=x.miny;
        if(x.maxy>maxy)maxy=x.maxy;
    }
    #if(flash9&&flib)@:ns("flibdel")#end public inline function toString(){
        return "{ x: "+minx+" y: "+miny+" w: "+width()+" h: "+height()+" }";
    }
}
